/*
 **********************************************************************
 * Copyright (c) 2013 Kernull.com
 * 
 * All rights reserved. No warranty, explicit or implicit, provided.
 * 
 * @author 	Christopher Aprea <caprea@kernull.com>
 * @date 	Oct 8, 2013
 * @project javapoker
 * 
 **********************************************************************
 */

package javapoker;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;

import javapoker.Card.CRank;
import javapoker.Card.CSuit;

// TODO: Auto-generated Javadoc
/**
 * The Class Deck.
 */
public class Deck 
{
    
    /** The cardlib. */
    private ArrayList<Card> cardlib;

    //Constructor
    /**
     * Instantiates a new deck.
     */
    public Deck()
    {
    	//Create the deck
        cardlib = new ArrayList<Card>();        
        
        addPack();
    }
    
    
    /**
     * Reset the deck to a newly opened pack. Cards are restored but not shuffled.
     */
    public void reset()
    {
    	empty();
    	addPack();
    }
    
    /**
     * Remove all cards from the deck so that there are 0 cards left
     */
    private void empty()
    {
    	cardlib.clear();
    }
    
    /**
     * Adds the standard 52 poker cards.
     */
    private void addPack()
    {
    	//Make one of every card, iterate over the enums
        for ( CSuit s : CSuit.values())
        {
        	if ( s != CSuit.UNKNOWN ) //skip the unknown suit
        	{	
        		for ( CRank  r : CRank.values())
            	{
        			if ( r != CRank.UNKNOWN) //skip the unknown rank
        			{
        				cardlib.add(new Card ( r, s));
        			}
            	}
        	}
        	
        }
    }
     
    //TODO: Implement numerous shuffle methods or non-pseudo random generator
    /**
     * Shuffle.
     */
    public void shuffle()
    {
    	
        int pos1, pos2;
        Random generator = new SecureRandom();
        Card temp;
        
    	int size = cardlib.size() -1;

        //Decks must be shuffled 7 time for randomness in real-life
        for (int j = 0; j<2; j++)
        {
        	for (short i=0; i<100; i++)
            {
        		//get two random positions in the deck
                pos1 = generator.nextInt( size );
                pos2 = generator.nextInt( size );

                temp = cardlib.get( pos1 ); //get first card
                cardlib.set( pos1 , cardlib.get( pos2 ) ); //move second card to first position
                cardlib.set( pos2, temp ); //move first card to second position
            }
        }
    }

    /**
     * Draw X cards from the library (deck) and return the drawn cards.
     *
     * @param i Number of cards to draw
     * @return The collection of Cards that were removed from the deck
     */
    public Collection<Card> drawX(int i)
    {
    	if (  i > count() )
    	{
    		throw new IllegalArgumentException("Number of cards to be drawn too many for remaining");
    	}
    	else if ( i < 0)
    	{
    		throw new IllegalArgumentException("Drawing illegal number of cards (< 0)");
    	}
    	
    	
    	Collection<Card> topcards = new ArrayList<Card>();
    	
    	
    	//Pull the cards off one by one, this is safe to remove/iterate over
    	for (int c =0; c < i; c++)
    	{
    		topcards.add(cardlib.remove(0));//remove top card
    	}
    	
    	return topcards;	//return those cards    	
    }
    
   
    /**
     * Draw one.
     *
     * @return the card
     */
    public Card drawOne()
    {       
    	//take the top card - where top is index 0
        return cardlib.remove( 0 );
    }

    /**
     * Gets the total cards.
     *
     * @return the total cards
     */
    public int count()
    {
        return cardlib.size();
        //we could use this method when making 
        //a complete poker game to see if we needed a new deck
    }
}